前天我提到了希望可以研究一下如何做 playbook 的模組化,今天就來整理一下有哪些方式可以幫助我們管理比較複雜的 playbook 吧。
第一個部分先來看看,在 Ansible 裡面我們可以如何去定義變數。
inventory 裡面可以直接定義變數,像是以下這個範例就會在 localhost 這個 host 上定義 foo
的值為 "bar"
。
[local]
localhost ansible_connection=local foo=bar
我們也可以針對整個 group 設定變數,像是這樣。
[local]
localhost ansible_connection=local
[local:vars]
foo=bar
但是,以上的方法都是要將變數寫進同一份檔案內,所以我們的變數會跟 host 綁在一起,某些情況下我們或許不希望這樣。
host_vars
/ group_vars
但還好 Ansible 也有提供分檔案的寫法,那就是把變數的定義放在 host_vars/
或是 group_vars/
底下,這兩個資料夾底下的檔名就對應著 host 或是 group。
舉例來說,若我們想要在 locahost 底下定義 foo=bar
的話,那麼可以在 inventory file 的同層目錄下的 host_vars/localhost
(可以加上副檔名)內,直接以 dictionary 定義變數們:
foo: bar
另外也支援 json 格式:
{
"foo": "bar"
}
而 group variable 也是類似的概念,不過只是改成在 local 這個 group 底下定義變數。最後需要注意一點,與 inventory 不同,這些定義變數的檔案並不支援 ini 格式。
vars_files
之前我們曾經有寫過,直接在 playbook 裡面使用 vars
定義變數,不過若是要分成不同檔案的話就要改成使用 vars_files
了。舉例來說,若我們把變數存在 vars.yml
,那麼 playbook 可以這樣寫。
---
- name: Read variable from file
hosts: all
vars_files:
- vars.yml
tasks:
- name: Print
ansible.builtin.debug:
var: foo
然後 vars.yml
長這樣:
foo: bar
另外,這種特性也可以讓我們方便的替換不同的檔案,很適合撰寫根據不同的環境 (e.g. dev, test) 來設定變數的 playbook,這部分可以參考凍仁大大之前寫的文章。
關於 task 的重用就沒有那麼多選項了,Ansible 提供了 import_task 跟 include_task 兩個 module 來幫助我們引用其他的 task,例如我們把 playbook 改成這樣:
---
- name: Read variable from file
hosts: all
vars_files:
- vars.yml
tasks:
- name: Print
include_tasks: print.yml
然後在 print.yml
寫入以下內容:
- name: Print
ansible.builtin.debug:
var: foo
再次執行之後就會發現跟原來一樣可以成功印出 foo
的內容。
那麼 import_tasks 跟 include_tasks 究竟有什麼不同呢?根據官方的說明,他們分別是靜態跟動態的,也就是處理時機的不同,import_tasks 會在 ansible-playbook
這個指令 parse playbook 的時候就把 task 檔案包進來,但是 include_tasks 是在執行到它的時候才會把 task 包進來。
除了 task,playbook 也是可以重用的,需要透過 import_playbook 來使用,而這部份就沒有提供 include 版本了,也就是說 playbook 的重用是沒有動態版本的。使用範例如下(假設剛剛的 playbook 叫做 var-test.yml
):
- import_playbook: var-test.yml
另存為 import.yml
,則執行 ansible-playbook import.yml
就跟執行 ansible-playbook var-test.yml
是等價的。
今天整理了該如何重用 playbook 裡面的內容,不過其實還有 role 的機制沒有講到,這部分就留到明天再來補充吧。